| /* |
| * Copyright (c) 2015 Intel Corporation |
| * Copyright (c) 2018 Nordic Semiconductor |
| * Copyright (c) 2019 Centaur Analytics, Inc |
| * Copyright 2023 NXP |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/kernel.h> |
| #include <zephyr/device.h> |
| #include <zephyr/drivers/watchdog.h> |
| #include <zephyr/sys/printk.h> |
| #include <stdbool.h> |
| |
| #define WDT_FEED_TRIES 5 |
| |
| /* |
| * To use this sample the devicetree's /aliases must have a 'watchdog0' property. |
| */ |
| #if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_window_watchdog) |
| #define WDT_MAX_WINDOW 100U |
| #elif DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_wdt) |
| /* Nordic supports a callback, but it has 61.2 us to complete before |
| * the reset occurs, which is too short for this sample to do anything |
| * useful. Explicitly disallow use of the callback. |
| */ |
| #define WDT_ALLOW_CALLBACK 0 |
| #elif DT_HAS_COMPAT_STATUS_OKAY(raspberrypi_pico_watchdog) |
| #define WDT_ALLOW_CALLBACK 0 |
| #elif DT_HAS_COMPAT_STATUS_OKAY(gd_gd32_wwdgt) |
| #define WDT_MAX_WINDOW 24U |
| #define WDT_MIN_WINDOW 18U |
| #define WDG_FEED_INTERVAL 12U |
| #elif DT_HAS_COMPAT_STATUS_OKAY(intel_tco_wdt) |
| #define WDT_ALLOW_CALLBACK 0 |
| #define WDT_MAX_WINDOW 3000U |
| #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_fs26_wdog) |
| #define WDT_MAX_WINDOW 1024U |
| #define WDT_MIN_WINDOW 320U |
| #define WDT_OPT 0 |
| #define WDG_FEED_INTERVAL (WDT_MIN_WINDOW + ((WDT_MAX_WINDOW - WDT_MIN_WINDOW) / 4)) |
| #endif |
| |
| #ifndef WDT_ALLOW_CALLBACK |
| #define WDT_ALLOW_CALLBACK 1 |
| #endif |
| |
| #ifndef WDT_MAX_WINDOW |
| #define WDT_MAX_WINDOW 1000U |
| #endif |
| |
| #ifndef WDT_MIN_WINDOW |
| #define WDT_MIN_WINDOW 0U |
| #endif |
| |
| #ifndef WDG_FEED_INTERVAL |
| #define WDG_FEED_INTERVAL 50U |
| #endif |
| |
| #ifndef WDT_OPT |
| #define WDT_OPT WDT_OPT_PAUSE_HALTED_BY_DBG |
| #endif |
| |
| #if WDT_ALLOW_CALLBACK |
| static void wdt_callback(const struct device *wdt_dev, int channel_id) |
| { |
| static bool handled_event; |
| |
| if (handled_event) { |
| return; |
| } |
| |
| wdt_feed(wdt_dev, channel_id); |
| |
| printk("Handled things..ready to reset\n"); |
| handled_event = true; |
| } |
| #endif /* WDT_ALLOW_CALLBACK */ |
| |
| int main(void) |
| { |
| int err; |
| int wdt_channel_id; |
| const struct device *const wdt = DEVICE_DT_GET(DT_ALIAS(watchdog0)); |
| |
| printk("Watchdog sample application\n"); |
| |
| if (!device_is_ready(wdt)) { |
| printk("%s: device not ready.\n", wdt->name); |
| return 0; |
| } |
| |
| struct wdt_timeout_cfg wdt_config = { |
| /* Reset SoC when watchdog timer expires. */ |
| .flags = WDT_FLAG_RESET_SOC, |
| |
| /* Expire watchdog after max window */ |
| .window.min = WDT_MIN_WINDOW, |
| .window.max = WDT_MAX_WINDOW, |
| }; |
| |
| #if WDT_ALLOW_CALLBACK |
| /* Set up watchdog callback. */ |
| wdt_config.callback = wdt_callback; |
| |
| printk("Attempting to test pre-reset callback\n"); |
| #else /* WDT_ALLOW_CALLBACK */ |
| printk("Callback in RESET_SOC disabled for this platform\n"); |
| #endif /* WDT_ALLOW_CALLBACK */ |
| |
| wdt_channel_id = wdt_install_timeout(wdt, &wdt_config); |
| if (wdt_channel_id == -ENOTSUP) { |
| /* IWDG driver for STM32 doesn't support callback */ |
| printk("Callback support rejected, continuing anyway\n"); |
| wdt_config.callback = NULL; |
| wdt_channel_id = wdt_install_timeout(wdt, &wdt_config); |
| } |
| if (wdt_channel_id < 0) { |
| printk("Watchdog install error\n"); |
| return 0; |
| } |
| |
| err = wdt_setup(wdt, WDT_OPT); |
| if (err < 0) { |
| printk("Watchdog setup error\n"); |
| return 0; |
| } |
| |
| #if WDT_MIN_WINDOW != 0 |
| /* Wait opening window. */ |
| k_msleep(WDT_MIN_WINDOW); |
| #endif |
| /* Feeding watchdog. */ |
| printk("Feeding watchdog %d times\n", WDT_FEED_TRIES); |
| for (int i = 0; i < WDT_FEED_TRIES; ++i) { |
| printk("Feeding watchdog...\n"); |
| wdt_feed(wdt, wdt_channel_id); |
| k_sleep(K_MSEC(WDG_FEED_INTERVAL)); |
| } |
| |
| /* Waiting for the SoC reset. */ |
| printk("Waiting for reset...\n"); |
| while (1) { |
| k_yield(); |
| } |
| return 0; |
| } |