| /* |
| * Copyright (c) 2016, Freescale Semiconductor, Inc. |
| * Copyright 2016-2017 NXP |
| * All rights reserved. |
| * |
| * SPDX-License-Identifier: BSD-3-Clause |
| */ |
| |
| #include "fsl_wwdt.h" |
| |
| /* Component ID definition, used by tools. */ |
| #ifndef FSL_COMPONENT_ID |
| #define FSL_COMPONENT_ID "platform.drivers.wwdt" |
| #endif |
| |
| /******************************************************************************* |
| * Prototypes |
| ******************************************************************************/ |
| |
| /*! |
| * @brief Gets the instance from the base address |
| * |
| * @param base WWDT peripheral base address |
| * |
| * @return The WWDT instance |
| */ |
| static uint32_t WWDT_GetInstance(WWDT_Type *base); |
| |
| /******************************************************************************* |
| * Variables |
| ******************************************************************************/ |
| /*! @brief Pointers to WWDT bases for each instance. */ |
| static WWDT_Type *const s_wwdtBases[] = WWDT_BASE_PTRS; |
| |
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
| /*! @brief Pointers to WWDT clocks for each instance. */ |
| static const clock_ip_name_t s_wwdtClocks[] = WWDT_CLOCKS; |
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
| |
| #if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) |
| #if !(defined(FSL_FEATURE_WWDT_HAS_NO_RESET) && FSL_FEATURE_WWDT_HAS_NO_RESET) |
| /*! @brief Pointers to WWDT resets for each instance. */ |
| static const reset_ip_name_t s_wwdtResets[] = WWDT_RSTS; |
| #endif |
| #endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ |
| |
| /******************************************************************************* |
| * Code |
| ******************************************************************************/ |
| static uint32_t WWDT_GetInstance(WWDT_Type *base) |
| { |
| uint32_t instance; |
| uint32_t wwdtArrayCount = (sizeof(s_wwdtBases) / sizeof(s_wwdtBases[0])); |
| |
| /* Find the instance index from base address mappings. */ |
| for (instance = 0; instance < wwdtArrayCount; instance++) |
| { |
| if (s_wwdtBases[instance] == base) |
| { |
| break; |
| } |
| } |
| |
| assert(instance < wwdtArrayCount); |
| |
| return instance; |
| } |
| |
| /******************************************************************************* |
| * Code |
| ******************************************************************************/ |
| |
| /*! |
| * brief Initializes WWDT configure sturcture. |
| * |
| * This function initializes the WWDT configure structure to default value. The default |
| * value are: |
| * code |
| * config->enableWwdt = true; |
| * config->enableWatchdogReset = false; |
| * config->enableWatchdogProtect = false; |
| * config->enableLockOscillator = false; |
| * config->windowValue = 0xFFFFFFU; |
| * config->timeoutValue = 0xFFFFFFU; |
| * config->warningValue = 0; |
| * endcode |
| * |
| * param config Pointer to WWDT config structure. |
| * see wwdt_config_t |
| */ |
| void WWDT_GetDefaultConfig(wwdt_config_t *config) |
| { |
| assert(config); |
| |
| /* Initializes the configure structure to zero. */ |
| memset(config, 0, sizeof(*config)); |
| |
| /* Enable the watch dog */ |
| config->enableWwdt = true; |
| /* Disable the watchdog timeout reset */ |
| config->enableWatchdogReset = false; |
| /* Disable the watchdog protection for updating the timeout value */ |
| config->enableWatchdogProtect = false; |
| /* Do not lock the watchdog oscillator */ |
| config->enableLockOscillator = false; |
| /* Windowing is not in effect */ |
| config->windowValue = 0xFFFFFFU; |
| /* Set the timeout value to the max */ |
| config->timeoutValue = 0xFFFFFFU; |
| /* No warning is provided */ |
| config->warningValue = 0; |
| /* Set clock frequency. */ |
| config->clockFreq_Hz = 0U; |
| } |
| |
| /*! |
| * brief Initializes the WWDT. |
| * |
| * This function initializes the WWDT. When called, the WWDT runs according to the configuration. |
| * |
| * Example: |
| * code |
| * wwdt_config_t config; |
| * WWDT_GetDefaultConfig(&config); |
| * config.timeoutValue = 0x7ffU; |
| * WWDT_Init(wwdt_base,&config); |
| * endcode |
| * |
| * param base WWDT peripheral base address |
| * param config The configuration of WWDT |
| */ |
| void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config) |
| { |
| assert(config); |
| /* The config->clockFreq_Hz must be set in order to config the delay time. */ |
| assert(config->clockFreq_Hz); |
| |
| uint32_t value = 0U; |
| uint32_t timeDelay = 0U; |
| |
| timeDelay = (SystemCoreClock / config->clockFreq_Hz + 1) * 3; |
| |
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
| /* Enable the WWDT clock */ |
| CLOCK_EnableClock(s_wwdtClocks[WWDT_GetInstance(base)]); |
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
| |
| #if !(defined(FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) && FSL_SDK_DISABLE_DRIVER_RESET_CONTROL) |
| #if !(defined(FSL_FEATURE_WWDT_HAS_NO_RESET) && FSL_FEATURE_WWDT_HAS_NO_RESET) |
| /* Reset the module. */ |
| RESET_PeripheralReset(s_wwdtResets[WWDT_GetInstance(base)]); |
| #endif |
| #endif /* FSL_SDK_DISABLE_DRIVER_RESET_CONTROL */ |
| |
| value = WWDT_MOD_WDEN(config->enableWwdt) | WWDT_MOD_WDRESET(config->enableWatchdogReset) | |
| WWDT_MOD_LOCK(config->enableLockOscillator); |
| /* Set configruation */ |
| base->TC = WWDT_TC_COUNT(config->timeoutValue); |
| base->MOD |= value; |
| base->WINDOW = WWDT_WINDOW_WINDOW(config->windowValue); |
| base->WARNINT = WWDT_WARNINT_WARNINT(config->warningValue); |
| WWDT_Refresh(base); |
| /* This WDPROTECT bit can be set once by software and is only cleared by a reset */ |
| if ((base->MOD & WWDT_MOD_WDPROTECT_MASK) == 0U) |
| { |
| /* Set the WDPROTECT bit after the Feed Sequence (0xAA, 0x55) with 3 WDCLK delay */ |
| while (timeDelay--) |
| { |
| __NOP(); |
| } |
| base->MOD |= WWDT_MOD_WDPROTECT(config->enableWatchdogProtect); |
| } |
| } |
| |
| /*! |
| * brief Shuts down the WWDT. |
| * |
| * This function shuts down the WWDT. |
| * |
| * param base WWDT peripheral base address |
| */ |
| void WWDT_Deinit(WWDT_Type *base) |
| { |
| WWDT_Disable(base); |
| |
| #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) |
| /* Disable the WWDT clock */ |
| CLOCK_DisableClock(s_wwdtClocks[WWDT_GetInstance(base)]); |
| #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ |
| } |
| |
| /*! |
| * brief Refreshes the WWDT timer. |
| * |
| * This function feeds the WWDT. |
| * This function should be called before WWDT timer is in timeout. Otherwise, a reset is asserted. |
| * |
| * param base WWDT peripheral base address |
| */ |
| void WWDT_Refresh(WWDT_Type *base) |
| { |
| uint32_t primaskValue = 0U; |
| |
| /* Disable the global interrupt to protect refresh sequence */ |
| primaskValue = DisableGlobalIRQ(); |
| base->FEED = WWDT_FIRST_WORD_OF_REFRESH; |
| base->FEED = WWDT_SECOND_WORD_OF_REFRESH; |
| EnableGlobalIRQ(primaskValue); |
| } |
| |
| /*! |
| * brief Clear WWDT flag. |
| * |
| * This function clears WWDT status flag. |
| * |
| * Example for clearing warning flag: |
| * code |
| * WWDT_ClearStatusFlags(wwdt_base, kWWDT_WarningFlag); |
| * endcode |
| * param base WWDT peripheral base address |
| * param mask The status flags to clear. This is a logical OR of members of the |
| * enumeration ::_wwdt_status_flags_t |
| */ |
| void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask) |
| { |
| /* Clear the WDINT bit so that we don't accidentally clear it */ |
| uint32_t reg = (base->MOD & (~WWDT_MOD_WDINT_MASK)); |
| |
| /* Clear timeout by writing a zero */ |
| if (mask & kWWDT_TimeoutFlag) |
| { |
| reg &= ~WWDT_MOD_WDTOF_MASK; |
| } |
| |
| /* Clear warning interrupt flag by writing a one */ |
| if (mask & kWWDT_WarningFlag) |
| { |
| reg |= WWDT_MOD_WDINT_MASK; |
| } |
| |
| base->MOD = reg; |
| } |