1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  * Copyright (c) 2016 Intel Corporation
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /**
9  * @file
10  * @brief Public API for counter and timer drivers
11  */
12 
13 #ifndef ZEPHYR_INCLUDE_DRIVERS_COUNTER_H_
14 #define ZEPHYR_INCLUDE_DRIVERS_COUNTER_H_
15 
16 /**
17  * @brief Counter Interface
18  * @defgroup counter_interface Counter Interface
19  * @since 1.14
20  * @version 0.8.0
21  * @ingroup io_interfaces
22  * @{
23  */
24 
25 #include <errno.h>
26 
27 #include <zephyr/types.h>
28 #include <stddef.h>
29 #include <zephyr/device.h>
30 #include <zephyr/sys_clock.h>
31 #include <stdbool.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /**
38  * @anchor COUNTER_FLAGS
39  * @name Counter device capabilities
40  * @{
41  */
42 
43 /**
44  * @brief Counter count up flag.
45  */
46 #define COUNTER_CONFIG_INFO_COUNT_UP BIT(0)
47 
48 /**@} */
49 
50 /**
51  * @anchor COUNTER_TOP_FLAGS
52  * @name Flags used by counter_top_cfg.
53  * @{
54  */
55 
56 /**
57  * @brief Flag preventing counter reset when top value is changed.
58  *
59  * If flags is set then counter is free running while top value is updated,
60  * otherwise counter is reset (see @ref counter_set_top_value()).
61  */
62 #define COUNTER_TOP_CFG_DONT_RESET BIT(0)
63 
64 /**
65  * @brief Flag instructing counter to reset itself if changing top value
66  *	  results in counter going out of new top value bound.
67  *
68  * See @ref COUNTER_TOP_CFG_DONT_RESET.
69  */
70 #define COUNTER_TOP_CFG_RESET_WHEN_LATE BIT(1)
71 
72 /**@} */
73 
74 /**
75  * @anchor COUNTER_ALARM_FLAGS
76  * @name Alarm configuration flags
77  *
78  * @brief Used in alarm configuration structure (@ref counter_alarm_cfg).
79  * @{ */
80 
81 /**
82  * @brief Counter alarm absolute value flag.
83  *
84  * Ticks relation to counter value. If set ticks are treated as absolute value,
85  * else it is relative to the counter reading performed during the call.
86  */
87 #define COUNTER_ALARM_CFG_ABSOLUTE BIT(0)
88 
89 /**
90  * @brief Alarm flag enabling immediate expiration when driver detects that
91  *	  absolute alarm was set too late.
92  *
93  * Alarm callback must be called from the same context as if it was set on time.
94  */
95 #define COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE  BIT(1)
96 
97 /**@} */
98 
99 /**
100  * @anchor COUNTER_GUARD_PERIOD_FLAGS
101  * @name Counter guard period flags
102  *
103  * @brief Used by @ref counter_set_guard_period and
104  *	  @ref counter_get_guard_period.
105  * @{ */
106 
107 /**
108  * @brief Identifies guard period needed for detection of late setting of
109  *	  absolute alarm (see @ref counter_set_channel_alarm).
110  */
111 #define COUNTER_GUARD_PERIOD_LATE_TO_SET BIT(0)
112 
113 /**@} */
114 
115 /** @brief Alarm callback
116  *
117  * @param dev       Pointer to the device structure for the driver instance.
118  * @param chan_id   Channel ID.
119  * @param ticks     Counter value that triggered the alarm.
120  * @param user_data User data.
121  */
122 typedef void (*counter_alarm_callback_t)(const struct device *dev,
123 					 uint8_t chan_id, uint32_t ticks,
124 					 void *user_data);
125 
126 /** @brief Alarm callback structure.
127  */
128 struct counter_alarm_cfg {
129 	/**
130 	 * Callback called on alarm (cannot be NULL).
131 	 */
132 	counter_alarm_callback_t callback;
133 	/**
134 	 * Number of ticks that triggers the alarm.
135 	 *
136 	 * It can be relative (to now) or an absolute value (see @ref
137 	 * COUNTER_ALARM_CFG_ABSOLUTE). Both, relative and absolute, alarm
138 	 * values can be any value between zero and the current top value (see
139 	 * @ref counter_get_top_value). When setting an absolute alarm value
140 	 * close to the current counter value there is a risk that the counter
141 	 * will have counted past the given absolute value before the driver
142 	 * manages to activate the alarm. Therefore a guard period can be
143 	 * defined that lets the driver decide unambiguously whether it is late
144 	 * or not (see @ref counter_set_guard_period). If the counter is clock
145 	 * driven then ticks can be converted to microseconds (see @ref
146 	 * counter_ticks_to_us). Alternatively, the counter implementation may
147 	 * count asynchronous events.
148 	 */
149 	uint32_t ticks;
150 	/**
151 	 * User data returned in callback.
152 	 */
153 	void *user_data;
154 	/**
155 	 * Alarm flags (see @ref COUNTER_ALARM_FLAGS).
156 	 */
157 	uint32_t flags;
158 };
159 
160 /** @brief Callback called when counter turns around.
161  *
162  * @param dev       Pointer to the device structure for the driver instance.
163  * @param user_data User data provided in @ref counter_set_top_value.
164  */
165 typedef void (*counter_top_callback_t)(const struct device *dev,
166 				       void *user_data);
167 
168 /** @brief Top value configuration structure.
169  */
170 struct counter_top_cfg {
171 	/**
172 	 * Top value.
173 	 */
174 	uint32_t ticks;
175 	/**
176 	 * Callback function (can be NULL).
177 	 */
178 	counter_top_callback_t callback;
179 	/**
180 	 * User data passed to callback function (not valid if callback is NULL).
181 	 */
182 	void *user_data;
183 	/**
184 	 * Flags (see @ref COUNTER_TOP_FLAGS).
185 	 */
186 	uint32_t flags;
187 };
188 
189 /** @brief Structure with generic counter features.
190  */
191 struct counter_config_info {
192 	/**
193 	 * Maximal (default) top value on which counter is reset (cleared or reloaded).
194 	 */
195 	uint32_t max_top_value;
196 	/**
197 	 * Frequency of the source clock if synchronous events are counted.
198 	 */
199 	uint32_t freq;
200 	/**
201 	 * Flags (see @ref COUNTER_FLAGS).
202 	 */
203 	uint8_t flags;
204 	/**
205 	 * Number of channels that can be used for setting alarm.
206 	 *
207 	 * @see counter_set_channel_alarm
208 	 */
209 	uint8_t channels;
210 };
211 
212 typedef int (*counter_api_start)(const struct device *dev);
213 typedef int (*counter_api_stop)(const struct device *dev);
214 typedef int (*counter_api_get_value)(const struct device *dev,
215 				     uint32_t *ticks);
216 typedef int (*counter_api_get_value_64)(const struct device *dev,
217 			uint64_t *ticks);
218 typedef int (*counter_api_set_alarm)(const struct device *dev,
219 				     uint8_t chan_id,
220 				     const struct counter_alarm_cfg *alarm_cfg);
221 typedef int (*counter_api_cancel_alarm)(const struct device *dev,
222 					uint8_t chan_id);
223 typedef int (*counter_api_set_top_value)(const struct device *dev,
224 					 const struct counter_top_cfg *cfg);
225 typedef uint32_t (*counter_api_get_pending_int)(const struct device *dev);
226 typedef uint32_t (*counter_api_get_top_value)(const struct device *dev);
227 typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev,
228 						 uint32_t flags);
229 typedef int (*counter_api_set_guard_period)(const struct device *dev,
230 						uint32_t ticks,
231 						uint32_t flags);
232 typedef uint32_t (*counter_api_get_freq)(const struct device *dev);
233 
234 __subsystem struct counter_driver_api {
235 	counter_api_start start;
236 	counter_api_stop stop;
237 	counter_api_get_value get_value;
238 	counter_api_get_value_64 get_value_64;
239 	counter_api_set_alarm set_alarm;
240 	counter_api_cancel_alarm cancel_alarm;
241 	counter_api_set_top_value set_top_value;
242 	counter_api_get_pending_int get_pending_int;
243 	counter_api_get_top_value get_top_value;
244 	counter_api_get_guard_period get_guard_period;
245 	counter_api_set_guard_period set_guard_period;
246 	counter_api_get_freq get_freq;
247 };
248 
249 /**
250  * @brief Function to check if counter is counting up.
251  *
252  * @param[in]  dev    Pointer to the device structure for the driver instance.
253  *
254  * @retval true if counter is counting up.
255  * @retval false if counter is counting down.
256  */
257 __syscall bool counter_is_counting_up(const struct device *dev);
258 
z_impl_counter_is_counting_up(const struct device * dev)259 static inline bool z_impl_counter_is_counting_up(const struct device *dev)
260 {
261 	const struct counter_config_info *config =
262 			(const struct counter_config_info *)dev->config;
263 
264 	return config->flags & COUNTER_CONFIG_INFO_COUNT_UP;
265 }
266 
267 /**
268  * @brief Function to get number of alarm channels.
269  *
270  * @param[in]  dev    Pointer to the device structure for the driver instance.
271  *
272  * @return Number of alarm channels.
273  */
274 __syscall uint8_t counter_get_num_of_channels(const struct device *dev);
275 
z_impl_counter_get_num_of_channels(const struct device * dev)276 static inline uint8_t z_impl_counter_get_num_of_channels(const struct device *dev)
277 {
278 	const struct counter_config_info *config =
279 			(const struct counter_config_info *)dev->config;
280 
281 	return config->channels;
282 }
283 
284 /**
285  * @brief Function to get counter frequency.
286  *
287  * @param[in]  dev    Pointer to the device structure for the driver instance.
288  *
289  * @return Frequency of the counter in Hz, or zero if the counter does
290  * not have a fixed frequency.
291  */
292 __syscall uint32_t counter_get_frequency(const struct device *dev);
293 
z_impl_counter_get_frequency(const struct device * dev)294 static inline uint32_t z_impl_counter_get_frequency(const struct device *dev)
295 {
296 	const struct counter_config_info *config =
297 			(const struct counter_config_info *)dev->config;
298 	const struct counter_driver_api *api =
299 				(struct counter_driver_api *)dev->api;
300 
301 	return api->get_freq ? api->get_freq(dev) : config->freq;
302 }
303 
304 /**
305  * @brief Function to convert microseconds to ticks.
306  *
307  * @param[in]  dev    Pointer to the device structure for the driver instance.
308  * @param[in]  us     Microseconds.
309  *
310  * @return Converted ticks. Ticks will be saturated if exceed 32 bits.
311  */
312 __syscall uint32_t counter_us_to_ticks(const struct device *dev, uint64_t us);
313 
z_impl_counter_us_to_ticks(const struct device * dev,uint64_t us)314 static inline uint32_t z_impl_counter_us_to_ticks(const struct device *dev,
315 					       uint64_t us)
316 {
317 	uint64_t ticks = (us * z_impl_counter_get_frequency(dev)) / USEC_PER_SEC;
318 
319 	return (ticks > (uint64_t)UINT32_MAX) ? UINT32_MAX : ticks;
320 }
321 
322 /**
323  * @brief Function to convert ticks to microseconds.
324  *
325  * @param[in]  dev    Pointer to the device structure for the driver instance.
326  * @param[in]  ticks  Ticks.
327  *
328  * @return Converted microseconds.
329  */
330 __syscall uint64_t counter_ticks_to_us(const struct device *dev, uint32_t ticks);
331 
z_impl_counter_ticks_to_us(const struct device * dev,uint32_t ticks)332 static inline uint64_t z_impl_counter_ticks_to_us(const struct device *dev,
333 					       uint32_t ticks)
334 {
335 	return ((uint64_t)ticks * USEC_PER_SEC) / z_impl_counter_get_frequency(dev);
336 }
337 
338 /**
339  * @brief Function to retrieve maximum top value that can be set.
340  *
341  * @param[in]  dev    Pointer to the device structure for the driver instance.
342  *
343  * @return Max top value.
344  */
345 __syscall uint32_t counter_get_max_top_value(const struct device *dev);
346 
z_impl_counter_get_max_top_value(const struct device * dev)347 static inline uint32_t z_impl_counter_get_max_top_value(const struct device *dev)
348 {
349 	const struct counter_config_info *config =
350 			(const struct counter_config_info *)dev->config;
351 
352 	return config->max_top_value;
353 }
354 
355 /**
356  * @brief Start counter device in free running mode.
357  *
358  * @param dev Pointer to the device structure for the driver instance.
359  *
360  * @retval 0 If successful.
361  * @retval Negative errno code if failure.
362  */
363 __syscall int counter_start(const struct device *dev);
364 
z_impl_counter_start(const struct device * dev)365 static inline int z_impl_counter_start(const struct device *dev)
366 {
367 	const struct counter_driver_api *api =
368 				(struct counter_driver_api *)dev->api;
369 
370 	return api->start(dev);
371 }
372 
373 /**
374  * @brief Stop counter device.
375  *
376  * @param dev Pointer to the device structure for the driver instance.
377  *
378  * @retval 0 If successful.
379  * @retval -ENOTSUP if the device doesn't support stopping the
380  *                        counter.
381  */
382 __syscall int counter_stop(const struct device *dev);
383 
z_impl_counter_stop(const struct device * dev)384 static inline int z_impl_counter_stop(const struct device *dev)
385 {
386 	const struct counter_driver_api *api =
387 				(struct counter_driver_api *)dev->api;
388 
389 	return api->stop(dev);
390 }
391 
392 /**
393  * @brief Get current counter value.
394  * @param dev Pointer to the device structure for the driver instance.
395  * @param ticks Pointer to where to store the current counter value
396  *
397  * @retval 0 If successful.
398  * @retval Negative error code on failure getting the counter value
399  */
400 __syscall int counter_get_value(const struct device *dev, uint32_t *ticks);
401 
z_impl_counter_get_value(const struct device * dev,uint32_t * ticks)402 static inline int z_impl_counter_get_value(const struct device *dev,
403 					   uint32_t *ticks)
404 {
405 	const struct counter_driver_api *api =
406 				(struct counter_driver_api *)dev->api;
407 
408 	return api->get_value(dev, ticks);
409 }
410 
411 /**
412  * @brief Get current counter 64-bit value.
413  * @param dev Pointer to the device structure for the driver instance.
414  * @param ticks Pointer to where to store the current counter value
415  *
416  * @retval 0 If successful.
417  * @retval Negative error code on failure getting the counter value
418  */
419 __syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks);
420 
z_impl_counter_get_value_64(const struct device * dev,uint64_t * ticks)421 static inline int z_impl_counter_get_value_64(const struct device *dev,
422 					   uint64_t *ticks)
423 {
424 	const struct counter_driver_api *api =
425 				(struct counter_driver_api *)dev->api;
426 
427 	if (!api->get_value_64) {
428 		return -ENOTSUP;
429 	}
430 
431 	return api->get_value_64(dev, ticks);
432 }
433 
434 /**
435  * @brief Set a single shot alarm on a channel.
436  *
437  * After expiration alarm can be set again, disabling is not needed. When alarm
438  * expiration handler is called, channel is considered available and can be
439  * set again in that context.
440  *
441  * @note API is not thread safe.
442  *
443  * @param dev		Pointer to the device structure for the driver instance.
444  * @param chan_id	Channel ID.
445  * @param alarm_cfg	Alarm configuration.
446  *
447  * @retval 0 If successful.
448  * @retval -ENOTSUP if request is not supported (device does not support
449  *		    interrupts or requested channel).
450  * @retval -EINVAL if alarm settings are invalid.
451  * @retval -ETIME  if absolute alarm was set too late.
452  * @retval -EBUSY  if alarm is already active.
453  */
454 __syscall int counter_set_channel_alarm(const struct device *dev,
455 					uint8_t chan_id,
456 					const struct counter_alarm_cfg *alarm_cfg);
457 
z_impl_counter_set_channel_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)458 static inline int z_impl_counter_set_channel_alarm(const struct device *dev,
459 						   uint8_t chan_id,
460 						   const struct counter_alarm_cfg *alarm_cfg)
461 {
462 	const struct counter_driver_api *api =
463 				(struct counter_driver_api *)dev->api;
464 
465 	if (chan_id >= counter_get_num_of_channels(dev)) {
466 		return -ENOTSUP;
467 	}
468 
469 	return api->set_alarm(dev, chan_id, alarm_cfg);
470 }
471 
472 /**
473  * @brief Cancel an alarm on a channel.
474  *
475  * @note API is not thread safe.
476  *
477  * @param dev		Pointer to the device structure for the driver instance.
478  * @param chan_id	Channel ID.
479  *
480  * @retval 0 If successful.
481  * @retval -ENOTSUP if request is not supported or the counter was not started
482  *		    yet.
483  */
484 __syscall int counter_cancel_channel_alarm(const struct device *dev,
485 					   uint8_t chan_id);
486 
z_impl_counter_cancel_channel_alarm(const struct device * dev,uint8_t chan_id)487 static inline int z_impl_counter_cancel_channel_alarm(const struct device *dev,
488 						      uint8_t chan_id)
489 {
490 	const struct counter_driver_api *api =
491 				(struct counter_driver_api *)dev->api;
492 
493 	if (chan_id >= counter_get_num_of_channels(dev)) {
494 		return -ENOTSUP;
495 	}
496 
497 	return api->cancel_alarm(dev, chan_id);
498 }
499 
500 /**
501  * @brief Set counter top value.
502  *
503  * Function sets top value and optionally resets the counter to 0 or top value
504  * depending on counter direction. On turnaround, counter can be reset and
505  * optional callback is periodically called. Top value can only be changed when
506  * there is no active channel alarm.
507  *
508  * @ref COUNTER_TOP_CFG_DONT_RESET prevents counter reset. When counter is
509  * running while top value is updated, it is possible that counter progresses
510  * outside the new top value. In that case, error is returned and optionally
511  * driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE).
512  *
513  * @param dev		Pointer to the device structure for the driver instance.
514  * @param cfg		Configuration. Cannot be NULL.
515  *
516  * @retval 0 If successful.
517  * @retval -ENOTSUP if request is not supported (e.g. top value cannot be
518  *		    changed or counter cannot/must be reset during top value
519 		    update).
520  * @retval -EBUSY if any alarm is active.
521  * @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value
522  *		  is smaller than current counter value (counter counting up).
523  */
524 __syscall int counter_set_top_value(const struct device *dev,
525 				    const struct counter_top_cfg *cfg);
526 
z_impl_counter_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)527 static inline int z_impl_counter_set_top_value(const struct device *dev,
528 					       const struct counter_top_cfg
529 					       *cfg)
530 {
531 	const struct counter_driver_api *api =
532 				(struct counter_driver_api *)dev->api;
533 
534 	if (cfg->ticks > counter_get_max_top_value(dev)) {
535 		return -EINVAL;
536 	}
537 
538 	return api->set_top_value(dev, cfg);
539 }
540 
541 /**
542  * @brief Function to get pending interrupts
543  *
544  * The purpose of this function is to return the interrupt
545  * status register for the device.
546  * This is especially useful when waking up from
547  * low power states to check the wake up source.
548  *
549  * @param dev Pointer to the device structure for the driver instance.
550  *
551  * @retval 1 if any counter interrupt is pending.
552  * @retval 0 if no counter interrupt is pending.
553  */
554 __syscall int counter_get_pending_int(const struct device *dev);
555 
z_impl_counter_get_pending_int(const struct device * dev)556 static inline int z_impl_counter_get_pending_int(const struct device *dev)
557 {
558 	const struct counter_driver_api *api =
559 				(struct counter_driver_api *)dev->api;
560 
561 	return api->get_pending_int(dev);
562 }
563 
564 /**
565  * @brief Function to retrieve current top value.
566  *
567  * @param[in]  dev    Pointer to the device structure for the driver instance.
568  *
569  * @return Top value.
570  */
571 __syscall uint32_t counter_get_top_value(const struct device *dev);
572 
z_impl_counter_get_top_value(const struct device * dev)573 static inline uint32_t z_impl_counter_get_top_value(const struct device *dev)
574 {
575 	const struct counter_driver_api *api =
576 				(struct counter_driver_api *)dev->api;
577 
578 	return api->get_top_value(dev);
579 }
580 
581 /**
582  * @brief Set guard period in counter ticks.
583  *
584  * When setting an absolute alarm value close to the current counter value there
585  * is a risk that the counter will have counted past the given absolute value
586  * before the driver manages to activate the alarm. If this would go unnoticed
587  * then the alarm would only expire after the timer has wrapped and reached the
588  * given absolute value again after a full timer period. This could take a long
589  * time in case of a 32 bit timer. Setting a sufficiently large guard period will
590  * help the driver detect unambiguously whether it is late or not.
591  *
592  * The guard period should be as many counter ticks as the driver will need at
593  * most to actually activate the alarm after the driver API has been called. If
594  * the driver finds that the counter has just passed beyond the given absolute
595  * tick value but is still close enough to fall within the guard period, it will
596  * assume that it is "late", i.e. that the intended expiry time has already passed.
597  * Depending on the @ref COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE flag the driver will
598  * either ignore the alarm or expire it immediately in such a case.
599  *
600  * If, however, the counter is past the given absolute tick value but outside
601  * the guard period, then the driver will assume that this is intentional and
602  * let the counter wrap around to/from zero before it expires.
603  *
604  * More precisely:
605  *
606  * - When counting upwards (see @ref COUNTER_CONFIG_INFO_COUNT_UP) the given
607  *   absolute tick value must be above (now + guard_period) % top_value to be
608  *   accepted by the driver.
609  * - When counting downwards, the given absolute tick value must be less than
610  *   (now + top_value - guard_period) % top_value to be accepted.
611  *
612  * Examples:
613  *
614  * - counting upwards, now = 4950, top value = 5000, guard period = 100:
615  *      absolute tick value >= (4950 + 100) % 5000 = 50
616  * - counting downwards, now = 50, top value = 5000, guard period = 100:
617  *      absolute tick value <= (50 + 5000 - * 100) % 5000 = 4950
618  *
619  * If you need only short alarm periods, you can set the guard period very high
620  * (e.g. half of the counter top value) which will make it highly unlikely that
621  * the counter will ever unintentionally wrap.
622  *
623  * The guard period is set to 0 on initialization (no protection).
624  *
625  * @param dev		Pointer to the device structure for the driver instance.
626  * @param ticks		Guard period in counter ticks.
627  * @param flags		See @ref COUNTER_GUARD_PERIOD_FLAGS.
628  *
629  * @retval 0 if successful.
630  * @retval -ENOTSUP if function or flags are not supported.
631  * @retval -EINVAL if ticks value is invalid.
632  */
633 __syscall int counter_set_guard_period(const struct device *dev,
634 					uint32_t ticks,
635 					uint32_t flags);
636 
z_impl_counter_set_guard_period(const struct device * dev,uint32_t ticks,uint32_t flags)637 static inline int z_impl_counter_set_guard_period(const struct device *dev,
638 						   uint32_t ticks, uint32_t flags)
639 {
640 	const struct counter_driver_api *api =
641 				(struct counter_driver_api *)dev->api;
642 
643 	if (!api->set_guard_period) {
644 		return -ENOTSUP;
645 	}
646 
647 	return api->set_guard_period(dev, ticks, flags);
648 }
649 
650 /**
651  * @brief Return guard period.
652  *
653  * @see counter_set_guard_period.
654  *
655  * @param dev	Pointer to the device structure for the driver instance.
656  * @param flags	See @ref COUNTER_GUARD_PERIOD_FLAGS.
657  *
658  * @return Guard period given in counter ticks or 0 if function or flags are
659  *	   not supported.
660  */
661 __syscall uint32_t counter_get_guard_period(const struct device *dev,
662 					    uint32_t flags);
663 
z_impl_counter_get_guard_period(const struct device * dev,uint32_t flags)664 static inline uint32_t z_impl_counter_get_guard_period(const struct device *dev,
665 							uint32_t flags)
666 {
667 	const struct counter_driver_api *api =
668 				(struct counter_driver_api *)dev->api;
669 
670 	return (api->get_guard_period) ? api->get_guard_period(dev, flags) : 0;
671 }
672 
673 #ifdef __cplusplus
674 }
675 #endif
676 
677 /**
678  * @}
679  */
680 
681 #include <zephyr/syscalls/counter.h>
682 
683 #endif /* ZEPHYR_INCLUDE_DRIVERS_COUNTER_H_ */
684