LCOV - code coverage report
Current view: top level - zephyr/drivers - counter.h Coverage Total Hit
Test: new.info Lines: 60.9 % 69 42
Test Date: 2025-09-25 19:22:35

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

Generated by: LCOV version 2.0-1