1 /*
2  * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 /**
36  * @file Definitions of utils used in the nRF 802.15.4 Service Layer.
37  *
38  */
39 
40 #ifndef NRF_802154_SL_UTILS_H__
41 #define NRF_802154_SL_UTILS_H__
42 
43 #include <stdbool.h>
44 #include <stdint.h>
45 #include <stdbool.h>
46 #include "nrfx.h"
47 
48 /**@brief RTC clock frequency. */
49 #define NRF_802154_SL_RTC_FREQUENCY               32768UL
50 
51 /**@brief Defines the number of microseconds in one second. */
52 #define NRF_802154_SL_US_PER_S                    1000000ULL
53 
54 /**@brief Number of microseconds in one RTC tick (rounded up). */
55 #define NRF_802154_SL_US_PER_TICK                 NRF_802154_SL_RTC_TICKS_TO_US(1)
56 
57 /**@brief Number of bits to shift RTC_FREQUENCY and US_PER_S to achieve the division by greatest common divisor. */
58 #define NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS 6
59 
60 /**@brief Ceil division helper. */
61 #define NRF_802154_SL_DIVIDE_AND_CEIL(A, B)       (((A) + (B)-1) / (B))
62 
63 /**@brief Defines the conversion of RTC ticks to microseconds (us). */
64 #define NRF_802154_SL_RTC_TICKS_TO_US(ticks)                                             \
65     NRF_802154_SL_DIVIDE_AND_CEIL(                                                       \
66         (ticks) * (NRF_802154_SL_US_PER_S >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS), \
67         (NRF_802154_SL_RTC_FREQUENCY >> NRF_802154_SL_FREQUENCY_US_PER_S_GCD_BITS))
68 
69 /**@brief Converts microseconds (us) to RTC ticks.
70  *
71  * @param time      Time is us to be converted to RTC ticks.
72  * @param round_up  Round up resulting value, otherwise the result is rounded down.
73  *
74  * @return Time converted to RTC ticks.
75  */
76 uint64_t NRF_802154_SL_US_TO_RTC_TICKS(uint64_t time, bool round_up);
77 
78 /**@brief Type holding MCU critical section state.
79  *
80  * Variable of this type is required to hold state saved by @ref nrf_802154_sl_mcu_critical_enter
81  * and restored by @ref nrf_802154_sl_mcu_critical_exit.
82  */
83 typedef uint32_t nrf_802154_sl_mcu_critical_state_t;
84 
85 /**@brief Enters critical section on MCU level.
86  *
87  * Use @ref nrf_802154_sl_mcu_critical_exit complementary. Consider following code:
88  * @code
89  * nrf_802154_sl_mcu_critical_state_t mcu_cs;
90  * nrf_802154_sl_mcu_critical_enter(mcu_cs);
91  * // do your critical stuff as fast as possible
92  * nrf_802154_sl_mcu_critical_exit(mcu_cs);
93  * @endcode
94  *
95  * @param mcu_critical_state    Variable of @ref nrf_802154_sl_mcu_critical_state_t where current
96  *                              state of MCU level critical section will be stored.
97  */
98 #define nrf_802154_sl_mcu_critical_enter(mcu_critical_state) \
99     do                                                       \
100     {                                                        \
101         (mcu_critical_state) = __get_PRIMASK();              \
102         __disable_irq();                                     \
103     }                                                        \
104     while (0)
105 
106 /**@brief Exits critical section on MCU level.
107  *
108  * This shall be used complementary to @ref nrf_802154_sl_mcu_critical_enter.
109  *
110  * @param mcu_critical_state    Variable of @ref nrf_802154_sl_mcu_critical_state_t where
111  *                              state of MCU level critical section is stored by
112  *                              former call to @ref nrf_802154_sl_mcu_critical_enter
113  */
114 #define nrf_802154_sl_mcu_critical_exit(mcu_critical_state) \
115     do                                                      \
116     {                                                       \
117         __set_PRIMASK(mcu_critical_state);                  \
118     }                                                       \
119     while (0)
120 
121 /**
122  * @brief Checks if the given time is in the future.
123  *
124  * The value of @p now is assumed to be based on a 64-bit time source that never overflows.
125  * These assumptions are met, for example, by @ref nrf_802154_sl_timer_current_time_get().
126  *
127  * @param[in]  now  Current time.
128  * @param[in]  t0   The time value to be checked.
129  *
130  * @retval true   Given time @p t0 is in future (compared to given @p now).
131  * @retval false  Given time @p t0 is not in future (compared to given @p now).
132  */
nrf_802154_sl_time64_is_in_future(uint64_t now,uint64_t t0)133 static inline bool nrf_802154_sl_time64_is_in_future(uint64_t now, uint64_t t0)
134 {
135     return now < t0;
136 }
137 
138 #endif // NRF_802154_SL_UTILS_H__
139