1 /*
2 * Copyright (c) 2019 Linaro Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/counter.h>
11 #include <zephyr/sys/printk.h>
12
13 #define DELAY 2000000
14 #define ALARM_CHANNEL_ID 0
15
16 struct counter_alarm_cfg alarm_cfg;
17
18 #if defined(CONFIG_BOARD_ATSAMD20_XPRO)
19 #define TIMER DT_NODELABEL(tc4)
20 #elif defined(CONFIG_SOC_FAMILY_SAM)
21 #define TIMER DT_NODELABEL(tc0)
22 #elif defined(CONFIG_COUNTER_MICROCHIP_MCP7940N)
23 #define TIMER DT_NODELABEL(extrtc0)
24 #elif defined(CONFIG_COUNTER_NRF_RTC)
25 #define TIMER DT_NODELABEL(rtc0)
26 #elif defined(CONFIG_COUNTER_TIMER_STM32)
27 #define TIMER DT_INST(0, st_stm32_counter)
28 #elif defined(CONFIG_COUNTER_RTC_STM32)
29 #define TIMER DT_INST(0, st_stm32_rtc)
30 #elif defined(CONFIG_COUNTER_SMARTBOND_TIMER)
31 #define TIMER DT_NODELABEL(timer3)
32 #elif defined(CONFIG_COUNTER_NATIVE_POSIX)
33 #define TIMER DT_NODELABEL(counter0)
34 #elif defined(CONFIG_COUNTER_XLNX_AXI_TIMER)
35 #define TIMER DT_INST(0, xlnx_xps_timer_1_00_a)
36 #elif defined(CONFIG_COUNTER_TMR_ESP32)
37 #define TIMER DT_NODELABEL(timer0)
38 #elif defined(CONFIG_COUNTER_MCUX_CTIMER)
39 #define TIMER DT_NODELABEL(ctimer0)
40 #elif defined(CONFIG_COUNTER_NXP_S32_SYS_TIMER)
41 #define TIMER DT_NODELABEL(stm0)
42 #elif defined(CONFIG_COUNTER_TIMER_GD32)
43 #define TIMER DT_NODELABEL(timer0)
44 #elif defined(CONFIG_COUNTER_GECKO_RTCC)
45 #define TIMER DT_NODELABEL(rtcc0)
46 #elif defined(CONFIG_COUNTER_GECKO_STIMER)
47 #define TIMER DT_NODELABEL(stimer0)
48 #elif defined(CONFIG_COUNTER_INFINEON_CAT1)
49 #define TIMER DT_NODELABEL(counter0_0)
50 #elif defined(CONFIG_COUNTER_AMBIQ)
51 #define TIMER DT_NODELABEL(counter0)
52 #elif defined(CONFIG_COUNTER_SNPS_DW)
53 #define TIMER DT_NODELABEL(timer0)
54 #elif defined(CONFIG_COUNTER_TIMER_RPI_PICO)
55 #define TIMER DT_NODELABEL(timer)
56 #endif
57
test_counter_interrupt_fn(const struct device * counter_dev,uint8_t chan_id,uint32_t ticks,void * user_data)58 static void test_counter_interrupt_fn(const struct device *counter_dev,
59 uint8_t chan_id, uint32_t ticks,
60 void *user_data)
61 {
62 struct counter_alarm_cfg *config = user_data;
63 uint32_t now_ticks;
64 uint64_t now_usec;
65 int now_sec;
66 int err;
67
68 err = counter_get_value(counter_dev, &now_ticks);
69 if (err) {
70 printk("Failed to read counter value (err %d)", err);
71 return;
72 }
73
74 now_usec = counter_ticks_to_us(counter_dev, now_ticks);
75 now_sec = (int)(now_usec / USEC_PER_SEC);
76
77 printk("!!! Alarm !!!\n");
78 printk("Now: %u\n", now_sec);
79
80 /* Set a new alarm with a double length duration */
81 config->ticks = config->ticks * 2U;
82
83 printk("Set alarm in %u sec (%u ticks)\n",
84 (uint32_t)(counter_ticks_to_us(counter_dev,
85 config->ticks) / USEC_PER_SEC),
86 config->ticks);
87
88 err = counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID,
89 user_data);
90 if (err != 0) {
91 printk("Alarm could not be set\n");
92 }
93 }
94
main(void)95 int main(void)
96 {
97 const struct device *const counter_dev = DEVICE_DT_GET(TIMER);
98 int err;
99
100 printk("Counter alarm sample\n\n");
101
102 if (!device_is_ready(counter_dev)) {
103 printk("device not ready.\n");
104 return 0;
105 }
106
107 counter_start(counter_dev);
108
109 alarm_cfg.flags = 0;
110 alarm_cfg.ticks = counter_us_to_ticks(counter_dev, DELAY);
111 alarm_cfg.callback = test_counter_interrupt_fn;
112 alarm_cfg.user_data = &alarm_cfg;
113
114 err = counter_set_channel_alarm(counter_dev, ALARM_CHANNEL_ID,
115 &alarm_cfg);
116 printk("Set alarm in %u sec (%u ticks)\n",
117 (uint32_t)(counter_ticks_to_us(counter_dev,
118 alarm_cfg.ticks) / USEC_PER_SEC),
119 alarm_cfg.ticks);
120
121 if (-EINVAL == err) {
122 printk("Alarm settings invalid\n");
123 } else if (-ENOTSUP == err) {
124 printk("Alarm setting request not supported\n");
125 } else if (err != 0) {
126 printk("Error\n");
127 }
128
129 while (1) {
130 k_sleep(K_FOREVER);
131 }
132 return 0;
133 }
134