1 /*
2 * Copyright 2022 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/drivers/watchdog.h>
9
10
11 /*
12 * To use this test, either the devicetree's /aliases must have a
13 * 'watchdog0' property, or one of the following watchdog compatibles
14 * must have an enabled node.
15 */
16 #if DT_NODE_HAS_STATUS_OKAY(DT_ALIAS(watchdog0))
17 #define WDT_NODE DT_ALIAS(watchdog0)
18 #elif DT_HAS_COMPAT_STATUS_OKAY(nxp_s32_swt)
19 #define WDT_NODE DT_INST(0, nxp_s32_swt)
20 #endif
21
22 #define WDT_FEED_TRIES 2
23 #define WDT_MAX_WINDOW 1000
24 #define WDT_TIMEOUT K_MSEC(1100)
25 #define SLEEP_TIME K_MSEC(500)
26 #define WDT_TEST_CB_TEST_VALUE 0xCB
27
28 static struct wdt_timeout_cfg m_cfg_wdt0;
29 static volatile int wdt_interrupted_flag;
30 static volatile int wdt_feed_flag;
31
32
wdt_callback(const struct device * dev,int channel_id)33 static void wdt_callback(const struct device *dev, int channel_id)
34 {
35 wdt_interrupted_flag += WDT_TEST_CB_TEST_VALUE;
36 zassert_equal(WDT_FEED_TRIES, wdt_feed_flag,
37 "%d: Invalid number of feeding (expected: %d)",
38 wdt_feed_flag, WDT_FEED_TRIES);
39 }
40
test_wdt_callback_reset_none(void)41 static int test_wdt_callback_reset_none(void)
42 {
43 int err;
44 const struct device *const wdt = DEVICE_DT_GET(WDT_NODE);
45
46 if (!device_is_ready(wdt)) {
47 TC_PRINT("WDT device is not ready\n");
48 return TC_FAIL;
49 }
50
51 m_cfg_wdt0.window.min = 0U;
52 m_cfg_wdt0.window.max = WDT_MAX_WINDOW;
53 m_cfg_wdt0.flags = WDT_FLAG_RESET_NONE;
54 m_cfg_wdt0.callback = wdt_callback;
55
56 err = wdt_install_timeout(wdt, &m_cfg_wdt0);
57 if (err == -ENOTSUP) {
58 TC_PRINT("Some of the options are not supported, skip\n");
59 return TC_SKIP;
60 } else if (err != 0) {
61 TC_PRINT("Watchdog install error\n");
62 return TC_FAIL;
63 }
64
65 err = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
66 if (err != 0) {
67 TC_PRINT("Watchdog setup error\n");
68 return TC_FAIL;
69 }
70
71 TC_PRINT("Feeding watchdog %d times\n", WDT_FEED_TRIES);
72 wdt_feed_flag = 0;
73 wdt_interrupted_flag = 0;
74 for (int i = 0; i < WDT_FEED_TRIES; ++i) {
75 TC_PRINT("Feeding %d\n", i+1);
76 wdt_feed(wdt, 0);
77 wdt_feed_flag++;
78 k_sleep(SLEEP_TIME);
79 }
80
81 k_timeout_t timeout = WDT_TIMEOUT;
82 uint64_t start_time = k_uptime_ticks();
83
84 while (wdt_interrupted_flag == 0) {
85 if (k_uptime_ticks() - start_time >= timeout.ticks) {
86 break;
87 }
88 }
89
90 zassert_equal(wdt_interrupted_flag, WDT_TEST_CB_TEST_VALUE,
91 "wdt callback failed");
92
93 err = wdt_disable(wdt);
94 if (err == -EPERM) {
95 TC_PRINT("Some of the options are not permitted, skip\n");
96 return TC_SKIP;
97 } else if (err != 0) {
98 TC_PRINT("Disable watchdog error\n");
99 return TC_FAIL;
100 }
101
102 return TC_PASS;
103 }
104
test_wdt_bad_window_max(void)105 static int test_wdt_bad_window_max(void)
106 {
107 int err;
108 const struct device *const wdt = DEVICE_DT_GET(WDT_NODE);
109
110 if (!device_is_ready(wdt)) {
111 TC_PRINT("WDT device is not ready\n");
112 return TC_FAIL;
113 }
114
115 m_cfg_wdt0.callback = NULL;
116 m_cfg_wdt0.flags = WDT_FLAG_RESET_NONE;
117 m_cfg_wdt0.window.max = 0U;
118 m_cfg_wdt0.window.min = 0U;
119 err = wdt_install_timeout(wdt, &m_cfg_wdt0);
120 if (err == -EINVAL) {
121 return TC_PASS;
122 }
123
124 return TC_FAIL;
125 }
126
127
ZTEST(wdt_basic_reset_none,test_wdt_callback_reset_none)128 ZTEST(wdt_basic_reset_none, test_wdt_callback_reset_none)
129 {
130 switch (test_wdt_callback_reset_none()) {
131 case TC_SKIP:
132 ztest_test_skip();
133 break;
134 case TC_PASS:
135 ztest_test_pass();
136 break;
137 default:
138 ztest_test_fail();
139 }
140 }
141
ZTEST(wdt_basic_reset_none,test_wdt_bad_window_max)142 ZTEST(wdt_basic_reset_none, test_wdt_bad_window_max)
143 {
144 zassert_true(test_wdt_bad_window_max() == TC_PASS);
145 }
146
147 ZTEST_SUITE(wdt_basic_reset_none, NULL, NULL, NULL, NULL, NULL);
148