1 /*
2  * Copyright (c) 2022 Nordic Semiconductor ASA
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include "test.h"
7 
8 #include <zephyr/device.h>
9 #include <zephyr/kernel.h>
10 #include <zephyr/logging/log.h>
11 #include <zephyr/pm/policy.h>
12 #include <zephyr/sys_clock.h>
13 
14 LOG_MODULE_REGISTER(app, CONFIG_APP_LOG_LEVEL);
15 
on_latency_changed(int32_t latency)16 static void on_latency_changed(int32_t latency)
17 {
18 	if (latency == SYS_FOREVER_US) {
19 		LOG_INF("Latency constraint changed: none");
20 	} else {
21 		LOG_INF("Latency constraint changed: %" PRId32 "ms",
22 			latency / USEC_PER_MSEC);
23 	}
24 }
25 
main(void)26 int main(void)
27 {
28 	struct pm_policy_latency_subscription subs;
29 	struct pm_policy_latency_request req;
30 	const struct device *dev;
31 
32 	dev = device_get_binding("dev_test");
33 	if (!device_is_ready(dev)) {
34 		LOG_ERR("Device not ready");
35 		return 0;
36 	}
37 
38 	pm_policy_latency_changed_subscribe(&subs, on_latency_changed);
39 
40 	/* test without any latency constraint */
41 	LOG_INF("Sleeping for 1.1 seconds, we should enter RUNTIME_IDLE");
42 	k_msleep(1100);
43 	LOG_INF("Sleeping for 1.2 seconds, we should enter SUSPEND_TO_IDLE");
44 	k_msleep(1200);
45 	LOG_INF("Sleeping for 1.3 seconds, we should enter STANDBY");
46 	k_msleep(1300);
47 
48 	/* add an application level latency constraint */
49 	LOG_INF("Setting latency constraint: 30ms");
50 	pm_policy_latency_request_add(&req, 30000);
51 
52 	/* test with an application level constraint */
53 	LOG_INF("Sleeping for 1.1 seconds, we should enter RUNTIME_IDLE");
54 	k_msleep(1100);
55 	LOG_INF("Sleeping for 1.2 seconds, we should enter SUSPEND_TO_IDLE");
56 	k_msleep(1200);
57 	LOG_INF("Sleeping for 1.3 seconds, we should enter SUSPEND_TO_IDLE");
58 	k_msleep(1300);
59 
60 	/* open test device (adds its own latency constraint) */
61 	LOG_INF("Opening test device");
62 	test_open(dev);
63 
64 	/* test with application + driver latency constraints */
65 	LOG_INF("Sleeping for 1.1 seconds, we should enter RUNTIME_IDLE");
66 	k_msleep(1100);
67 	LOG_INF("Sleeping for 1.2 seconds, we should enter RUNTIME_IDLE");
68 	k_msleep(1200);
69 	LOG_INF("Sleeping for 1.3 seconds, we should enter RUNTIME_IDLE");
70 	k_msleep(1300);
71 
72 	/* update application level latency constraint */
73 	LOG_INF("Updating latency constraint: 10ms");
74 	pm_policy_latency_request_update(&req, 10000);
75 
76 	/* test with updated application + driver latency constraints */
77 	LOG_INF("Sleeping for 1.1 seconds, we should stay ACTIVE");
78 	k_msleep(1100);
79 	LOG_INF("Sleeping for 1.2 seconds, we should stay ACTIVE");
80 	k_msleep(1200);
81 	LOG_INF("Sleeping for 1.3 seconds, we should stay ACTIVE");
82 	k_msleep(1300);
83 
84 	/* restore application level latency constraint */
85 	LOG_INF("Updating latency constraint: 30ms");
86 	pm_policy_latency_request_update(&req, 30000);
87 
88 	/* close test device (removes its own latency constraint) */
89 	LOG_INF("Closing test device");
90 	test_close(dev);
91 
92 	/* test again with an application level constraint */
93 	LOG_INF("Sleeping for 1.1 seconds, we should enter RUNTIME_IDLE");
94 	k_msleep(1100);
95 	LOG_INF("Sleeping for 1.2 seconds, we should enter SUSPEND_TO_IDLE");
96 	k_msleep(1200);
97 	LOG_INF("Sleeping for 1.3 seconds, we should enter SUSPEND_TO_IDLE");
98 	k_msleep(1300);
99 
100 	/* remove application level constraint and terminate */
101 	LOG_INF("Removing latency constraints");
102 	pm_policy_latency_request_remove(&req);
103 
104 	pm_policy_latency_changed_unsubscribe(&subs);
105 
106 	LOG_INF("Finished, we should now enter STANDBY");
107 	return 0;
108 }
109