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