mirror of https://github.com/ARMmbed/mbed-os.git
115 lines
3.7 KiB
C
115 lines
3.7 KiB
C
/**
|
|
*******************************************************************************
|
|
* @file watchdog_api.c
|
|
* @brief Implementation of watchdog_api
|
|
* @internal
|
|
* @author ON Semiconductor
|
|
******************************************************************************
|
|
* Copyright 2018 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
|
|
* All rights reserved. This software and/or documentation is licensed by ON Semiconductor
|
|
* under limited terms and conditions. The terms and conditions pertaining to the software
|
|
* and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
|
|
* (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
|
|
* if applicable the software license agreement. Do not use this software and/or
|
|
* documentation unless you have carefully read and you agree to the limited terms and
|
|
* conditions. By using this software and/or documentation, you agree to the limited
|
|
* terms and conditions.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
|
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
|
* ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
|
|
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
|
* @endinternal
|
|
*
|
|
*/
|
|
#include "watchdog_api.h"
|
|
#if DEVICE_WATCHDOG
|
|
|
|
#include "clock.h" // Peripheral clock control definitions.
|
|
#include "wdt_map.h" // Watchdog hardware register definitions.
|
|
#include "memory_map.h" // Pointer to watchdog peripheral in memory.
|
|
|
|
|
|
// watchdog_api feature definitions
|
|
#define WDT_MAX_TIMEOUT_MS ((uint32_t)8000)
|
|
#define WDT_CAN_UPDATE ((boolean)True)
|
|
#define WDT_CAN_STOP ((boolean)True)
|
|
|
|
// WDT LOAD register definitions
|
|
#define WDT_MAX_LOAD_VAL ((uint32_t)0x3FFFF)
|
|
#define WDT_TICKS_PER_MS (WDT_MAX_LOAD_VAL / WDT_MAX_TIMEOUT_MS)
|
|
|
|
// WDT KICK register definitions
|
|
#define WDT_KICK_VAL ((uint32_t)1)
|
|
|
|
// WDT LOCK register definitions
|
|
#define WDT_LOCK_DISABLE ((uint32_t)0x1ACCE551)
|
|
#define WDT_LOCK_ENABLE ((uint32_t)0x00000000)
|
|
|
|
|
|
watchdog_status_t hal_watchdog_init(const watchdog_config_t *config)
|
|
{
|
|
if (!config || config->timeout_ms > WDT_MAX_TIMEOUT_MS || config->timeout_ms == 0) {
|
|
return WATCHDOG_STATUS_INVALID_ARGUMENT;
|
|
}
|
|
|
|
if (!CLOCK_IS_ENABLED(CLOCK_WDOG)) {
|
|
CLOCK_ENABLE(CLOCK_WDOG);
|
|
}
|
|
|
|
// Disable write lock in case WDT is being reconfigured.
|
|
WDTREG->LOCK = WDT_LOCK_DISABLE;
|
|
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_ANY);
|
|
WDTREG->LOAD = config->timeout_ms * WDT_TICKS_PER_MS;
|
|
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_LOAD);
|
|
WDTREG->CONTROL.BITS.WDT_EN = True;
|
|
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_CONTROL);
|
|
WDTREG->LOCK = WDT_LOCK_ENABLE;
|
|
|
|
return WATCHDOG_STATUS_OK;
|
|
}
|
|
|
|
void hal_watchdog_kick(void)
|
|
{
|
|
// Write any value to kick watchdog.
|
|
WDTREG->KICK = WDT_KICK_VAL;
|
|
}
|
|
|
|
watchdog_status_t hal_watchdog_stop(void)
|
|
{
|
|
WDTREG->LOCK = WDT_LOCK_DISABLE;
|
|
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_ANY);
|
|
WDTREG->CONTROL.BITS.WDT_EN = False;
|
|
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_ANY);
|
|
CLOCK_DISABLE(CLOCK_WDOG);
|
|
|
|
return WATCHDOG_STATUS_OK;
|
|
}
|
|
|
|
uint32_t hal_watchdog_get_reload_value(void)
|
|
{
|
|
while (WDTREG->STATUS.BITS.WRITE_BUSY_LOAD);
|
|
return WDTREG->LOAD / WDT_TICKS_PER_MS;
|
|
}
|
|
|
|
watchdog_features_t hal_watchdog_get_platform_features(void)
|
|
{
|
|
const watchdog_features_t features = {
|
|
.max_timeout = WDT_MAX_TIMEOUT_MS,
|
|
.update_config = WDT_CAN_UPDATE,
|
|
.disable_watchdog = WDT_CAN_STOP
|
|
};
|
|
|
|
return features;
|
|
}
|
|
|
|
|
|
#endif // DEVICE_WATCHDOG
|
|
|