blob: 7a0560303e4402b5b45ed5a046d03fd47bfb3091 [file] [log] [blame]
/***************************************************************************//**
* @file em_wdog.h
* @brief Watchdog (WDOG) peripheral API
* @version 5.6.0
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#ifndef EM_WDOG_H
#define EM_WDOG_H
#include "em_device.h"
#if defined(WDOG_COUNT) && (WDOG_COUNT > 0)
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup WDOG
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** Default WDOG instance for deprecated functions. */
#if !defined(DEFAULT_WDOG)
#if defined(WDOG0)
#define DEFAULT_WDOG WDOG0
#elif defined(WDOG)
#define DEFAULT_WDOG WDOG
#endif
#endif
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** Watchdog clock selection. */
#if defined(_WDOG_CTRL_CLKSEL_MASK)
typedef enum {
wdogClkSelULFRCO = _WDOG_CTRL_CLKSEL_ULFRCO, /**< Ultra low frequency (1 kHz) clock */
wdogClkSelLFRCO = _WDOG_CTRL_CLKSEL_LFRCO, /**< Low frequency RC oscillator */
wdogClkSelLFXO = _WDOG_CTRL_CLKSEL_LFXO /**< Low frequency crystal oscillator */
} WDOG_ClkSel_TypeDef;
#endif
/** Watchdog period selection. */
typedef enum {
wdogPeriod_9 = 0x0, /**< 9 clock periods */
wdogPeriod_17 = 0x1, /**< 17 clock periods */
wdogPeriod_33 = 0x2, /**< 33 clock periods */
wdogPeriod_65 = 0x3, /**< 65 clock periods */
wdogPeriod_129 = 0x4, /**< 129 clock periods */
wdogPeriod_257 = 0x5, /**< 257 clock periods */
wdogPeriod_513 = 0x6, /**< 513 clock periods */
wdogPeriod_1k = 0x7, /**< 1025 clock periods */
wdogPeriod_2k = 0x8, /**< 2049 clock periods */
wdogPeriod_4k = 0x9, /**< 4097 clock periods */
wdogPeriod_8k = 0xA, /**< 8193 clock periods */
wdogPeriod_16k = 0xB, /**< 16385 clock periods */
wdogPeriod_32k = 0xC, /**< 32769 clock periods */
wdogPeriod_64k = 0xD, /**< 65537 clock periods */
wdogPeriod_128k = 0xE, /**< 131073 clock periods */
wdogPeriod_256k = 0xF /**< 262145 clock periods */
} WDOG_PeriodSel_TypeDef;
#if defined(_WDOG_CTRL_WARNSEL_MASK) \
|| defined(_WDOG_CFG_WARNSEL_MASK)
/** Select watchdog warning timeout period as percentage of timeout. */
typedef enum {
wdogWarnDisable = 0,
wdogWarnTime25pct = 1,
wdogWarnTime50pct = 2,
wdogWarnTime75pct = 3,
} WDOG_WarnSel_TypeDef;
#endif
#if defined(_WDOG_CTRL_WINSEL_MASK) \
|| defined(_WDOG_CFG_WINSEL_MASK)
/** Select watchdog illegal window limit. */
typedef enum {
wdogIllegalWindowDisable = 0,
wdogIllegalWindowTime12_5pct = 1,
wdogIllegalWindowTime25_0pct = 2,
wdogIllegalWindowTime37_5pct = 3,
wdogIllegalWindowTime50_0pct = 4,
wdogIllegalWindowTime62_5pct = 5,
wdogIllegalWindowTime75_0pct = 6,
wdogIllegalWindowTime87_5pct = 7,
} WDOG_WinSel_TypeDef;
#endif
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** Watchdog initialization structure. */
typedef struct {
/** Enable watchdog when initialization completed. */
bool enable;
/** Counter keeps running during debug halt. */
bool debugRun;
/** Counter keeps running when in EM2. */
bool em2Run;
/** Counter keeps running when in EM3. */
bool em3Run;
/** Block EMU from entering EM4. */
bool em4Block;
/** Block SW from disabling LFRCO/LFXO oscillators. */
#if defined(_WDOG_CTRL_SWOSCBLOCK_MASK)
bool swoscBlock;
#endif
/** Block SW from modifying the configuration (a reset is needed to reconfigure). */
bool lock;
/** Clock source to use for watchdog. */
#if defined(_WDOG_CTRL_CLKSEL_MASK)
WDOG_ClkSel_TypeDef clkSel;
#endif
/** Watchdog timeout period. */
WDOG_PeriodSel_TypeDef perSel;
#if defined(_WDOG_CTRL_WARNSEL_MASK) \
|| defined(_WDOG_CFG_WARNSEL_MASK)
/** Select warning time as % of the watchdog timeout */
WDOG_WarnSel_TypeDef warnSel;
#endif
#if defined(_WDOG_CTRL_WINSEL_MASK) \
|| defined(_WDOG_CFG_WINSEL_MASK)
/** Select illegal window time as % of the watchdog timeout */
WDOG_WinSel_TypeDef winSel;
#endif
#if defined(_WDOG_CTRL_WDOGRSTDIS_MASK) \
|| defined(_WDOG_CFG_WDOGRSTDIS_MASK)
/** Disable watchdog reset output if true */
bool resetDisable;
#endif
} WDOG_Init_TypeDef;
/** Suggested default configuration for WDOG initialization structure. */
#if defined(_WDOG_CFG_MASK)
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* Do not lock WDOG configuration. */ \
wdogPeriod_256k, /* Set longest possible timeout period. */ \
wdogWarnDisable, /* Disable warning interrupt. */ \
wdogIllegalWindowDisable, /* Disable illegal window interrupt. */ \
false /* Do not disable reset. */ \
}
#elif defined(_WDOG_CTRL_WARNSEL_MASK) \
&& defined(_WDOG_CTRL_WDOGRSTDIS_MASK) \
&& defined(_WDOG_CTRL_WINSEL_MASK)
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* Do not block disabling LFRCO/LFXO in CMU. */ \
false, /* Do not lock WDOG configuration. */ \
wdogClkSelULFRCO, /* Select 1kHZ WDOG oscillator. */ \
wdogPeriod_256k, /* Set longest possible timeout period. */ \
wdogWarnDisable, /* Disable warning interrupt. */ \
wdogIllegalWindowDisable, /* Disable illegal window interrupt. */ \
false /* Do not disable reset. */ \
}
#else
#define WDOG_INIT_DEFAULT \
{ \
true, /* Start watchdog when initialization is done. */ \
false, /* WDOG is not counting during debug halt. */ \
false, /* WDOG is not counting when in EM2. */ \
false, /* WDOG is not counting when in EM3. */ \
false, /* EM4 can be entered. */ \
false, /* Do not block disabling LFRCO/LFXO in CMU. */ \
false, /* Do not lock WDOG configuration. */ \
wdogClkSelULFRCO, /* Select 1kHZ WDOG oscillator. */ \
wdogPeriod_256k /* Set longest possible timeout period. */ \
}
#endif
/*******************************************************************************
***************************** PROTOTYPES **********************************
******************************************************************************/
void WDOGn_Enable(WDOG_TypeDef *wdog, bool enable);
void WDOGn_Feed(WDOG_TypeDef *wdog);
void WDOGn_Init(WDOG_TypeDef *wdog, const WDOG_Init_TypeDef *init);
void WDOGn_Lock(WDOG_TypeDef *wdog);
void WDOGn_Unlock(WDOG_TypeDef *wdog);
#if defined(_WDOG_IF_MASK)
/***************************************************************************//**
* @brief
* Clear one or more pending WDOG interrupts.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to clear. Use a set of interrupt flags OR-ed
* together to clear multiple interrupt sources.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntClear(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IF_CLR = flags;
#else
wdog->IFC = flags;
#endif
}
/***************************************************************************//**
* @brief
* Disable one or more WDOG interrupts.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to disable. Use a set of interrupt flags OR-ed
* together to disable multiple interrupt.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntDisable(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IEN_CLR = flags;
#else
wdog->IEN &= ~flags;
#endif
}
/***************************************************************************//**
* @brief
* Enable one or more WDOG interrupts.
*
* @note
* Depending on the use, a pending interrupt may already be set prior to
* enabling the interrupt. To ignore a pending interrupt, consider using
* WDOG_IntClear() prior to enabling the interrupt.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to enable. Use a set of interrupt flags OR-ed
* together to set multiple interrupt.
******************************************************************************/
__STATIC_INLINE void WDOGn_IntEnable(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IEN_SET = flags;
#else
wdog->IEN |= flags;
#endif
}
/***************************************************************************//**
* @brief
* Get pending WDOG interrupt flags.
*
* @note
* The event bits are not cleared by the use of this function.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @return
* Pending WDOG interrupt sources. Returns a set of interrupt flags OR-ed
* together for the interrupt sources set.
******************************************************************************/
__STATIC_INLINE uint32_t WDOGn_IntGet(WDOG_TypeDef *wdog)
{
return wdog->IF;
}
/***************************************************************************//**
* @brief
* Get enabled and pending WDOG interrupt flags.
*
* @details
* Useful for handling more interrupt sources in the same interrupt handler.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @return
* Pending and enabled WDOG interrupt sources. Returns a set of interrupt
* flags OR-ed together for the interrupt sources set.
******************************************************************************/
__STATIC_INLINE uint32_t WDOGn_IntGetEnabled(WDOG_TypeDef *wdog)
{
uint32_t tmp;
tmp = wdog->IEN;
/* Bitwise AND of pending and enabled interrupt flags. */
return wdog->IF & tmp;
}
/***************************************************************************//**
* @brief
* Set one or more pending WDOG interrupts from SW.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
*
* @param[in] flags
* WDOG interrupt sources to set to pending. Use a set of interrupt flags
* (WDOG_IFS_nnn).
******************************************************************************/
__STATIC_INLINE void WDOGn_IntSet(WDOG_TypeDef *wdog, uint32_t flags)
{
#if defined(WDOG_HAS_SET_CLEAR)
wdog->IF_SET = flags;
#else
wdog->IFS = flags;
#endif
}
#endif
/***************************************************************************//**
* @brief
* Get enabled status of the watchdog.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
******************************************************************************/
__STATIC_INLINE bool WDOGn_IsEnabled(WDOG_TypeDef *wdog)
{
#if defined(_WDOG_EN_MASK)
return (wdog->EN & _WDOG_EN_EN_MASK) == WDOG_EN_EN;
#else
return (wdog->CTRL & _WDOG_CTRL_EN_MASK) == WDOG_CTRL_EN;
#endif
}
/***************************************************************************//**
* @brief
* Get locked status of the watchdog.
*
* @param[in] wdog
* Pointer to WDOG peripheral register block.
******************************************************************************/
__STATIC_INLINE bool WDOGn_IsLocked(WDOG_TypeDef *wdog)
{
#if defined(_WDOG_STATUS_MASK)
return (wdog->STATUS & _WDOG_STATUS_LOCK_MASK) == WDOG_STATUS_LOCK_LOCKED;
#else
return (wdog->CTRL & _WDOG_CTRL_LOCK_MASK) == WDOG_CTRL_LOCK;
#endif
}
/***************************************************************************//**
* @brief
* Enable/disable the watchdog timer.
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_Enable().
* This function uses @ref DEFAULT_WDOG.
*
* @param[in] enable
* Set to true to enable watchdog, false to disable. Watchdog cannot be
* disabled if watchdog has been locked.
******************************************************************************/
__STATIC_INLINE void WDOG_Enable(bool enable)
{
WDOGn_Enable(DEFAULT_WDOG, enable);
}
/***************************************************************************//**
* @brief
* Feed the watchdog.
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_Feed().
* This function uses @ref DEFAULT_WDOG.
******************************************************************************/
__STATIC_INLINE void WDOG_Feed(void)
{
WDOGn_Feed(DEFAULT_WDOG);
}
/***************************************************************************//**
* @brief
* Initialize watchdog (assuming the watchdog configuration has not been
* locked).
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_Init().
* This function uses @ref DEFAULT_WDOG.
*
* @param[in] init
* Structure holding watchdog configuration. A default setting
* #WDOG_INIT_DEFAULT is available for initialization.
******************************************************************************/
__STATIC_INLINE void WDOG_Init(const WDOG_Init_TypeDef *init)
{
WDOGn_Init(DEFAULT_WDOG, init);
}
/***************************************************************************//**
* @brief
* Lock the watchdog configuration.
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_Lock().
* This function uses @ref DEFAULT_WDOG.
******************************************************************************/
__STATIC_INLINE void WDOG_Lock(void)
{
WDOGn_Lock(DEFAULT_WDOG);
}
/***************************************************************************//**
* @brief
* Get enabled status of the watchdog.
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_IsEnabled().
* This function uses @ref DEFAULT_WDOG.
******************************************************************************/
__STATIC_INLINE bool WDOG_IsEnabled(void)
{
return WDOGn_IsEnabled(DEFAULT_WDOG);
}
/***************************************************************************//**
* @brief
* Get locked status of the watchdog.
*
* @deprecated
* Deprecated function. New code should use @ref WDOGn_IsLocked().
* This function uses @ref DEFAULT_WDOG.
******************************************************************************/
__STATIC_INLINE bool WDOG_IsLocked(void)
{
return WDOGn_IsLocked(DEFAULT_WDOG);
}
/** @} (end addtogroup WDOG) */
/** @} (end addtogroup emlib) */
#ifdef __cplusplus
}
#endif
#endif /* defined(WDOG_COUNT) && (WDOG_COUNT > 0) */
#endif /* EM_WDOG_H */