LCOV - code coverage report
Current view: top level - zephyr/drivers - counter.h Hit Total Coverage
Test: new.info Lines: 41 66 62.1 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           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           1 : #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           1 : #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           1 : #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           1 : #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           1 : #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           1 : #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           1 : 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           1 : struct counter_alarm_cfg {
     129             :         /**
     130             :          * Callback called on alarm (cannot be NULL).
     131             :          */
     132           1 :         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           1 :         uint32_t ticks;
     150             :         /**
     151             :          * User data returned in callback.
     152             :          */
     153           1 :         void *user_data;
     154             :         /**
     155             :          * Alarm flags (see @ref COUNTER_ALARM_FLAGS).
     156             :          */
     157           1 :         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           1 : typedef void (*counter_top_callback_t)(const struct device *dev,
     166             :                                        void *user_data);
     167             : 
     168             : /** @brief Top value configuration structure.
     169             :  */
     170           1 : struct counter_top_cfg {
     171             :         /**
     172             :          * Top value.
     173             :          */
     174           1 :         uint32_t ticks;
     175             :         /**
     176             :          * Callback function (can be NULL).
     177             :          */
     178           1 :         counter_top_callback_t callback;
     179             :         /**
     180             :          * User data passed to callback function (not valid if callback is NULL).
     181             :          */
     182           1 :         void *user_data;
     183             :         /**
     184             :          * Flags (see @ref COUNTER_TOP_FLAGS).
     185             :          */
     186           1 :         uint32_t flags;
     187             : };
     188             : 
     189             : /** @brief Structure with generic counter features.
     190             :  */
     191           1 : struct counter_config_info {
     192             :         /**
     193             :          * Maximal (default) top value on which counter is reset (cleared or reloaded).
     194             :          */
     195           1 :         uint32_t max_top_value;
     196             :         /**
     197             :          * Frequency of the source clock if synchronous events are counted.
     198             :          */
     199           1 :         uint32_t freq;
     200             :         /**
     201             :          * Flags (see @ref COUNTER_FLAGS).
     202             :          */
     203           1 :         uint8_t flags;
     204             :         /**
     205             :          * Number of channels that can be used for setting alarm.
     206             :          *
     207             :          * @see counter_set_channel_alarm
     208             :          */
     209           1 :         uint8_t channels;
     210             : };
     211             : 
     212           0 : typedef int (*counter_api_start)(const struct device *dev);
     213           0 : typedef int (*counter_api_stop)(const struct device *dev);
     214           0 : typedef int (*counter_api_get_value)(const struct device *dev,
     215             :                                      uint32_t *ticks);
     216           0 : typedef int (*counter_api_get_value_64)(const struct device *dev,
     217             :                         uint64_t *ticks);
     218           0 : typedef int (*counter_api_set_alarm)(const struct device *dev,
     219             :                                      uint8_t chan_id,
     220             :                                      const struct counter_alarm_cfg *alarm_cfg);
     221           0 : typedef int (*counter_api_cancel_alarm)(const struct device *dev,
     222             :                                         uint8_t chan_id);
     223           0 : typedef int (*counter_api_set_top_value)(const struct device *dev,
     224             :                                          const struct counter_top_cfg *cfg);
     225           0 : typedef uint32_t (*counter_api_get_pending_int)(const struct device *dev);
     226           0 : typedef uint32_t (*counter_api_get_top_value)(const struct device *dev);
     227           0 : typedef uint32_t (*counter_api_get_guard_period)(const struct device *dev,
     228             :                                                  uint32_t flags);
     229           0 : typedef int (*counter_api_set_guard_period)(const struct device *dev,
     230             :                                                 uint32_t ticks,
     231             :                                                 uint32_t flags);
     232           0 : typedef uint32_t (*counter_api_get_freq)(const struct device *dev);
     233             : 
     234           0 : __subsystem struct counter_driver_api {
     235           0 :         counter_api_start start;
     236           0 :         counter_api_stop stop;
     237           0 :         counter_api_get_value get_value;
     238           0 :         counter_api_get_value_64 get_value_64;
     239           0 :         counter_api_set_alarm set_alarm;
     240           0 :         counter_api_cancel_alarm cancel_alarm;
     241           0 :         counter_api_set_top_value set_top_value;
     242           0 :         counter_api_get_pending_int get_pending_int;
     243           0 :         counter_api_get_top_value get_top_value;
     244           0 :         counter_api_get_guard_period get_guard_period;
     245           0 :         counter_api_set_guard_period set_guard_period;
     246           0 :         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           1 : __syscall bool counter_is_counting_up(const struct device *dev);
     258             : 
     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           1 : __syscall uint8_t counter_get_num_of_channels(const struct device *dev);
     275             : 
     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           1 : __syscall uint32_t counter_get_frequency(const struct device *dev);
     293             : 
     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           1 : __syscall uint32_t counter_us_to_ticks(const struct device *dev, uint64_t us);
     313             : 
     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           1 : __syscall uint64_t counter_ticks_to_us(const struct device *dev, uint32_t ticks);
     331             : 
     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           1 : __syscall uint32_t counter_get_max_top_value(const struct device *dev);
     346             : 
     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           1 : __syscall int counter_start(const struct device *dev);
     364             : 
     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           1 : __syscall int counter_stop(const struct device *dev);
     383             : 
     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           1 : __syscall int counter_get_value(const struct device *dev, uint32_t *ticks);
     401             : 
     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           1 : __syscall int counter_get_value_64(const struct device *dev, uint64_t *ticks);
     420             : 
     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           1 : __syscall int counter_set_channel_alarm(const struct device *dev,
     455             :                                         uint8_t chan_id,
     456             :                                         const struct counter_alarm_cfg *alarm_cfg);
     457             : 
     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           1 : __syscall int counter_cancel_channel_alarm(const struct device *dev,
     485             :                                            uint8_t chan_id);
     486             : 
     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           1 : __syscall int counter_set_top_value(const struct device *dev,
     525             :                                     const struct counter_top_cfg *cfg);
     526             : 
     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           1 : __syscall int counter_get_pending_int(const struct device *dev);
     555             : 
     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           1 : __syscall uint32_t counter_get_top_value(const struct device *dev);
     572             : 
     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           1 : __syscall int counter_set_guard_period(const struct device *dev,
     634             :                                         uint32_t ticks,
     635             :                                         uint32_t flags);
     636             : 
     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           1 : __syscall uint32_t counter_get_guard_period(const struct device *dev,
     662             :                                             uint32_t flags);
     663             : 
     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_ */

Generated by: LCOV version 1.14