1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/devicetree/clocks.h>
10 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
11
12 #if DT_NODE_EXISTS(DT_ALIAS(sample_device))
13 #define SAMPLE_CLOCK_NODE DT_CLOCKS_CTLR(DT_ALIAS(sample_device))
14 #elif DT_NODE_EXISTS(DT_ALIAS(sample_clock))
15 #define SAMPLE_CLOCK_NODE DT_ALIAS(sample_clock)
16 #endif
17
18 #define SAMPLE_CLOCK_NAME DT_NODE_FULL_NAME(SAMPLE_CLOCK_NODE)
19
20 #define SAMPLE_NOTIFY_TIMEOUT K_SECONDS(2)
21 #define SAMPLE_PRE_REQUEST_TIMEOUT K_SECONDS(CONFIG_SAMPLE_PRE_REQUEST_TIMEOUT)
22 #define SAMPLE_KEEP_REQUEST_TIMEOUT K_SECONDS(CONFIG_SAMPLE_KEEP_REQUEST_TIMEOUT)
23
24 const struct device *sample_clock_dev = DEVICE_DT_GET(SAMPLE_CLOCK_NODE);
25
26 static K_SEM_DEFINE(sample_sem, 0, 1);
27
sample_notify_cb(struct onoff_manager * mgr,struct onoff_client * cli,uint32_t state,int res)28 static void sample_notify_cb(struct onoff_manager *mgr,
29 struct onoff_client *cli,
30 uint32_t state,
31 int res)
32 {
33 ARG_UNUSED(mgr);
34 ARG_UNUSED(cli);
35 ARG_UNUSED(state);
36 ARG_UNUSED(res);
37
38 k_sem_give(&sample_sem);
39 }
40
main(void)41 int main(void)
42 {
43 struct onoff_client cli;
44 int ret;
45 int res;
46 int64_t req_start_uptime;
47 int64_t req_stop_uptime;
48
49 printk("\n");
50 printk("clock name: %s\n", SAMPLE_CLOCK_NAME);
51 printk("minimum frequency request: %uHz\n", CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ);
52 printk("minimum accuracy request: %uPPM\n", CONFIG_SAMPLE_CLOCK_ACCURACY_PPM);
53 printk("minimum precision request: %u\n", CONFIG_SAMPLE_CLOCK_PRECISION);
54
55 const struct nrf_clock_spec spec = {
56 .frequency = CONFIG_SAMPLE_CLOCK_FREQUENCY_HZ,
57 .accuracy = CONFIG_SAMPLE_CLOCK_ACCURACY_PPM,
58 .precision = CONFIG_SAMPLE_CLOCK_PRECISION,
59 };
60
61 sys_notify_init_callback(&cli.notify, sample_notify_cb);
62
63 k_sleep(SAMPLE_PRE_REQUEST_TIMEOUT);
64
65 printk("\n");
66 printk("requesting minimum clock specs\n");
67 req_start_uptime = k_uptime_get();
68 ret = nrf_clock_control_request(sample_clock_dev, &spec, &cli);
69 if (ret < 0) {
70 printk("minimum clock specs could not be met\n");
71 return 0;
72 }
73
74 ret = k_sem_take(&sample_sem, SAMPLE_NOTIFY_TIMEOUT);
75 if (ret < 0) {
76 printk("timed out waiting for clock to meet request\n");
77 return 0;
78 }
79
80 req_stop_uptime = k_uptime_get();
81
82 ret = sys_notify_fetch_result(&cli.notify, &res);
83 if (ret < 0) {
84 printk("sys notify fetch failed\n");
85 return 0;
86 }
87
88 if (res < 0) {
89 printk("failed to apply request to clock\n");
90 return 0;
91 }
92
93 printk("request applied to clock in %llims\n", req_stop_uptime - req_start_uptime);
94 k_sleep(SAMPLE_KEEP_REQUEST_TIMEOUT);
95
96 printk("\n");
97 printk("releasing requested clock specs\n");
98 ret = nrf_clock_control_release(sample_clock_dev, &spec);
99 if (ret < 0) {
100 printk("failed to release requested clock specs\n");
101 return 0;
102 }
103
104 printk("clock spec request released\n");
105 return 0;
106 }
107